#ifndef _VEC2_H_
#define _VEC2_H_

#include <math.h>

#define CROSS_ALLOWED_ERROR 1.f/16.f

typedef struct {
	float x,y;
} vec2;

static vec2 vec2XY(float x, float y) {
	return (vec2){x,y};
}
static vec2 vec2Polar(float a, float dist) {
	return (vec2){cosf(a)*dist, sinf(a)*dist};
}

static vec2 vec2Add(vec2 v, vec2 w) {
	return (vec2){v.x+w.x, v.y+w.y};
}
static vec2 vec2Sub(vec2 v, vec2 w) {
	return (vec2){v.x-w.x, v.y-w.y};
}
static vec2 vec2Scale(vec2 v, float scale) {
	return (vec2){v.x*scale, v.y*scale};
}
static float vec2LenSq(vec2 v) {
	return v.x*v.x + v.y*v.y;
}
static float vec2Len(vec2 v) {
	return sqrtf(vec2LenSq(v));
}
static float vec2Angle(vec2 v) {
	return atan2f(v.y, v.x);
}
static float vec2Dot(vec2 v, vec2 w) {
	return v.x*w.x + v.y*w.y;
}
static float vec2DiffSq(vec2 v, vec2 w) {
	return vec2LenSq(vec2Sub(v,w));
}
static float vec2Diff(vec2 v, vec2 w) {
	return sqrtf(vec2LenSq(vec2Sub(v,w)));
}
static int vec2Comp(vec2 v, vec2 w) {
	return (v.x == w.x && v.y == w.y);
}
static int vec2Cross(vec2 v1, vec2 v2, vec2 w1, vec2 w2) { // returns whether the given lines cross. (1=cross,0=not)
	// First, calculate y=ax+b formula's
	vec2 v = vec2Sub(v1,v2);
	vec2 resV;
	if(v.x == 0) { // If x equals zero, the formula causes zero division problems
		vec2 w = vec2Sub(w1,w2);
		vec2 resW;
		if(w.x == 0) {
			return 0;
		}
		resW.x = w.y/w.x;
		resW.y = w1.y-w1.x*resW.x;
		
		float cross = resW.x*v1.x+resW.y;
		if(cross - CROSS_ALLOWED_ERROR > fminf(v1.y,v2.y) && cross + CROSS_ALLOWED_ERROR < fmaxf(v1.y,v2.y) && v1.x - CROSS_ALLOWED_ERROR > fminf(w1.x,w2.x) && v1.x + CROSS_ALLOWED_ERROR < fmaxf(w1.x,w2.x)) {
			return 1;
		} else {
			return 0;
		}
	}
	resV.x = v.y/v.x;
	resV.y = v1.y-v1.x*resV.x;
	
	vec2 w = vec2Sub(w1,w2);
	vec2 resW;
	if(w.x == 0) {
		float cross = resV.x*w1.x+resV.y;
		if(cross - CROSS_ALLOWED_ERROR > fminf(w1.y,w2.y) && cross + CROSS_ALLOWED_ERROR < fmaxf(w1.y,w2.y) && w1.x - CROSS_ALLOWED_ERROR > fminf(v1.x,v2.x) && w1.x + CROSS_ALLOWED_ERROR < fmaxf(v1.x,v2.x)) {
			return 1;
		} else {
			return 0;
		}
	}
	resW.x = w.y/w.x;
	resW.y = w1.y-w1.x*resW.x;
	
	
	vec2 diff = vec2Sub(resV,resW);
	if(diff.x == 0) return 0; // lines are parallel
	
	float cross = (-diff.y)/diff.x;
	
	if(cross - CROSS_ALLOWED_ERROR > fminf(v1.x,v2.x) && cross + CROSS_ALLOWED_ERROR < fmaxf(v1.x,v2.x) && cross - CROSS_ALLOWED_ERROR > fminf(w1.x,w2.x) && cross + CROSS_ALLOWED_ERROR < fmaxf(w1.x,w2.x)) {
		return 1;
	} else {
		return 0;
	}
}

#endif

